home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / nethack.lha / nethack-3.1 / src / end.c < prev    next >
C/C++ Source or Header  |  1993-01-25  |  17KB  |  717 lines

  1. /*    SCCS Id: @(#)end.c    3.1    93/01/15    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #define NEED_VARARGS    /* comment line for pre-compiled headers */
  6.  
  7. #include "hack.h"
  8. #include "eshk.h"
  9. #ifndef NO_SIGNAL
  10. #include <signal.h>
  11. #endif
  12.  
  13. STATIC_PTR int NDECL(done_intr);
  14. static void FDECL(disclose,(int,BOOLEAN_P));
  15. static struct obj *FDECL(get_valuables, (struct obj *));
  16. static void FDECL(savelife, (int));
  17.  
  18. /*
  19.  * The order of these needs to match the macros in hack.h.
  20.  */
  21. static const char NEARDATA *deaths[] = {        /* the array of death */
  22.     "died", "choked", "poisoned", "starvation", "drowning",
  23.     "burning", "crushed", "turned to stone", "genocided",
  24.     "panic", "trickery",
  25.     "quit", "escaped", "ascended"
  26. };
  27.  
  28. static const char NEARDATA *ends[] = {        /* "when you..." */
  29.     "died", "choked", "were poisoned", "starved", "drowned",
  30.     "burned", "were crushed", "turned to stone", "were genocided",
  31.     "panicked", "were tricked",
  32.     "quit", "escaped", "ascended"
  33. };
  34.  
  35. int
  36. done1()
  37. {
  38. #ifndef NO_SIGNAL
  39.     (void) signal(SIGINT,SIG_IGN);
  40. #endif
  41.     if(flags.ignintr) {
  42. #ifndef NO_SIGNAL
  43.         (void) signal(SIGINT, (SIG_RET_TYPE) done1);
  44. #endif
  45.         clear_nhwindow(WIN_MESSAGE);
  46.         curs_on_u();
  47.         wait_synch();
  48.         if(multi > 0) nomul(0);
  49.         return 0;
  50.     }
  51.     return done2();
  52. }
  53.  
  54. int
  55. done2()
  56. {
  57.     if(yn("Really quit?") == 'n') {
  58. #ifndef NO_SIGNAL
  59.         (void) signal(SIGINT, (SIG_RET_TYPE) done1);
  60. #endif
  61.         clear_nhwindow(WIN_MESSAGE);
  62.         curs_on_u();
  63.         wait_synch();
  64.         if(multi > 0) nomul(0);
  65.         if(multi == 0) {
  66.             u.uinvulnerable = FALSE;    /* avoid ctrl-C bug -dlc */
  67.             u.usleep = 0;
  68.         }
  69.         return 0;
  70.     }
  71. #if defined(WIZARD) && (defined(UNIX) || defined(VMS) || defined(LATTICE))
  72.     if(wizard) {
  73. # ifdef VMS
  74.         const char *tmp = "Enter debugger?";
  75. # else
  76. #  ifdef LATTICE
  77.         const char *tmp = "Create SnapShot?";
  78. #  else
  79.         const char *tmp = "Dump core?";
  80. #  endif
  81. # endif
  82.         if(yn(tmp) == 'y') {
  83.         (void) signal(SIGINT, (SIG_RET_TYPE) done1);
  84.         exit_nhwindows(NULL);
  85. #ifdef AMIGA
  86.         Abort(0);
  87. #else
  88. # ifdef SYSV
  89.         (void)
  90. # endif
  91.             abort();
  92. #endif
  93.         }
  94.     }
  95. #endif
  96. #ifndef LINT
  97.     done(QUIT);
  98. #endif
  99.     return 0;
  100. }
  101.  
  102. STATIC_PTR
  103. int
  104. done_intr(){
  105.     done_stopprint++;
  106. #ifndef NO_SIGNAL
  107.     (void) signal(SIGINT, SIG_IGN);
  108. # if defined(UNIX) || defined(VMS)
  109.     (void) signal(SIGQUIT, SIG_IGN);
  110. # endif
  111. #endif /* NO_SIGNAL /* */
  112.     return 0;
  113. }
  114.  
  115. #if defined(UNIX) || defined(VMS)
  116. static
  117. int
  118. done_hangup(){
  119.     done_hup++;
  120.     (void)signal(SIGHUP, SIG_IGN);
  121.     (void)done_intr();
  122.     return 0;
  123. }
  124. #endif
  125.  
  126. void
  127. done_in_by(mtmp)
  128. register struct monst *mtmp;
  129. {
  130.     char buf[BUFSZ];
  131.  
  132.     You("die...");
  133.     buf[0] = '\0';
  134.     if (type_is_pname(mtmp->data) || (mtmp->data->geno & G_UNIQ)) {
  135.          if (!(type_is_pname(mtmp->data) && (mtmp->data->geno & G_UNIQ)))
  136.         Strcat(buf, "the ");
  137.          killer_format = KILLED_BY;
  138.     }
  139.     if (mtmp->minvis)
  140.         Strcat(buf, "invisible ");
  141.     if (Hallucination)
  142.         Strcat(buf, "hallucinogen-distorted ");
  143.  
  144.     if(mtmp->data == &mons[PM_GHOST]) {
  145.         register char *gn = (char *) mtmp->mextra;
  146.         if (!Hallucination && !mtmp->minvis && *gn) {
  147.             Strcat(buf, "the ");
  148.             killer_format = KILLED_BY;
  149.         }
  150.         Sprintf(eos(buf), (*gn ? "ghost of %s" : "ghost%s"), gn);
  151.     } else if(mtmp->isshk) {
  152.         Sprintf(eos(buf), "%s %s, the shopkeeper",
  153.             (mtmp->female ? "Ms." : "Mr."), shkname(mtmp));
  154.         killer_format = KILLED_BY;
  155.     } else if (mtmp->ispriest || mtmp->isminion) {
  156.         killer = priestname(mtmp);
  157.         if (!strncmp(killer, "the ", 4)) Strcat(buf, killer+4);
  158.         else Strcat(buf, killer);
  159.     } else Strcat(buf, mtmp->data->mname);
  160.     if (mtmp->mnamelth) Sprintf(eos(buf), " called %s", NAME(mtmp));
  161.     killer = buf;
  162.     if (mtmp->data->mlet == S_WRAITH)
  163.         u.ugrave_arise = PM_WRAITH;
  164.     else if (mtmp->data->mlet == S_MUMMY)
  165.         u.ugrave_arise = (pl_character[0]=='E') ?
  166.                         PM_ELF_MUMMY : PM_HUMAN_MUMMY;
  167.     else if (mtmp->data->mlet == S_VAMPIRE)
  168.         u.ugrave_arise = PM_VAMPIRE;
  169.     if (u.ugrave_arise > -1 && (mons[u.ugrave_arise].geno & G_GENOD))
  170.         u.ugrave_arise = -1;
  171.     if (mtmp->data->mlet == S_COCKATRICE)
  172.         done(STONING);
  173.     else
  174.         done(DIED);
  175.     return;
  176. }
  177.  
  178. /*VARARGS1*/
  179. boolean panicking;
  180. extern boolean hu;    /* from save.c */
  181.  
  182. void
  183. panic VA_DECL(const char *, str)
  184.     VA_START(str);
  185.     VA_INIT(str, char *);
  186.  
  187.     if(panicking++)
  188. #ifdef AMIGA
  189.         Abort(0);
  190. #else
  191. # ifdef SYSV
  192.         (void)
  193. # endif
  194.         abort();    /* avoid loops - this should never happen*/
  195. #endif
  196.  
  197.     if (flags.window_inited) exit_nhwindows(NULL);
  198.     flags.window_inited = 0; /* they're gone; force raw_print()ing */
  199.  
  200.     raw_print(" Suddenly, the dungeon collapses.");
  201. #if defined(WIZARD) && !defined(MICRO)
  202.     if(!wizard) {
  203.         raw_printf("Report error to %s and it may be possible to rebuild.",
  204. # ifdef WIZARD_NAME    /*(KR1ED)*/
  205.         WIZARD_NAME);
  206. # else
  207.         WIZARD);
  208. # endif
  209.     }
  210.     set_error_savefile();
  211.     hu = FALSE;
  212.     (void) dosave0();
  213. #endif
  214.     {
  215.         char buf[BUFSZ];
  216.         Vsprintf(buf,str,VA_ARGS);
  217.         raw_print(buf);
  218.     }
  219. #if defined(WIZARD) && (defined(UNIX) || defined(VMS) || defined(LATTICE))
  220.     if (wizard)
  221. # ifdef AMIGA
  222.         Abort(0);
  223. # else
  224. #  ifdef SYSV
  225.         (void)
  226. #  endif
  227.             abort();    /* generate core dump */
  228. # endif
  229. #endif
  230.     VA_END();
  231.     done(PANICKED);
  232. }
  233.  
  234. static void
  235. disclose(how,taken)
  236. int how;
  237. boolean taken;
  238. {
  239.     char    c;
  240.     char    qbuf[QBUFSZ];
  241.  
  242.     if(invent) {
  243.         if(taken)
  244.         Sprintf(qbuf,"Do you want to see what you had when you %s?",
  245.             (how == QUIT) ? "quit" : "died");
  246.         else
  247.         Strcpy(qbuf,"Do you want your possessions identified?");
  248.         if ((c = yn_function(qbuf, ynqchars, 'y')) == 'y') {
  249.         /* New dump format by maartenj@cs.vu.nl */
  250.         struct obj *obj;
  251.  
  252.         for(obj = invent; obj && !done_stopprint; obj = obj->nobj) {
  253.             makeknown(obj->otyp);
  254.             obj->known = obj->bknown = obj->dknown = obj->rknown = 1;
  255.         }
  256.         (void) display_inventory(NULL, FALSE);
  257.         container_contents(invent, TRUE, TRUE);
  258.         }
  259.         if (c == 'q')  done_stopprint++;
  260.         if (taken) {
  261.         /* paybill has already given the inventory locations
  262.          * in the shop and put it on the main object list
  263.          */
  264.         struct obj *obj;
  265.  
  266.         for(obj = invent; obj; obj = obj->nobj) {
  267.             obj->owornmask = 0;
  268.             if(rn2(5)) curse(obj);
  269.         }
  270.         invent = (struct obj *) 0;
  271.         }
  272.     }
  273.  
  274.     if (!done_stopprint) {
  275.         c = yn_function("Do you want to see your intrinsics?",ynqchars,'y');
  276.         if (c == 'y') enlightenment(TRUE);    /* final */
  277.         if (c == 'q') done_stopprint++;
  278.     }
  279.  
  280. }
  281.  
  282. /* try to get the player back in a viable state after being killed */
  283. static void
  284. savelife(how)
  285. int how;
  286. {
  287.     u.uswldtim = 0;
  288.     u.uhp = u.uhpmax;
  289.     if (u.uhunger < 500) {
  290.         u.uhunger = 500;
  291.         newuhs(FALSE);
  292.     }
  293.     if (how == CHOKING) init_uhunger();
  294.     nomovemsg = "You survived that attempt on your life.";
  295.     flags.move = 0;
  296.     if(multi > 0) multi = 0; else multi = -1;
  297.     if(u.utrap && u.utraptype == TT_LAVA) u.utrap = 0;
  298.     flags.botl = 1;
  299.     u.ugrave_arise = -1;
  300.     curs_on_u();
  301. }
  302.  
  303. /*
  304.  *  Get valuables from the given list. NOTE: The list is destroyed as it is
  305.  *  processed, so don't expect to use it again!
  306.  */
  307. static struct obj *
  308. get_valuables(list)
  309.     struct obj *list;
  310. {
  311.     struct obj *obj, *next_obj, *c_vals, *temp;
  312.     struct obj *valuables = (struct obj *)0;
  313.  
  314.     for (obj = list; obj; obj = next_obj) {
  315.     if (Is_container(obj) && obj->cobj) {
  316.         c_vals = get_valuables(obj->cobj);
  317.  
  318.         if (c_vals) {
  319.         /* find the end of the list */
  320.         for (temp = c_vals; temp->nobj; temp = temp->nobj) ;
  321.  
  322.         temp->nobj = valuables;
  323.         valuables = c_vals;
  324.         }
  325.     }
  326.  
  327.     next_obj = obj->nobj;
  328.  
  329.     if ((obj->oclass == GEM_CLASS && obj->otyp < LUCKSTONE)
  330.         || obj->oclass == AMULET_CLASS) {
  331.         obj->nobj = valuables;
  332.         valuables = obj;
  333.     }
  334.     }
  335.     return valuables;
  336. }
  337.  
  338. /* Be careful not to call panic from here! */
  339. void
  340. done(how)
  341. int how;
  342. {
  343.     struct permonst *upmon;
  344.     boolean taken;
  345.     char kilbuf[BUFSZ], pbuf[BUFSZ];
  346.     winid endwin = WIN_ERR;
  347.     boolean have_windows = flags.window_inited;
  348.  
  349.     /* kilbuf: used to copy killer in case it comes from something like
  350.      *    xname(), which would otherwise get overwritten when we call
  351.      *    xname() when listing possessions
  352.      * pbuf: holds Sprintf'd output for raw_print and putstr
  353.      */
  354.     if (how == ASCENDED)
  355.         killer_format = NO_KILLER_PREFIX;
  356.     /* Avoid killed by "a" burning or "a" starvation */
  357.     if (!killer && (how == STARVING || how == BURNING))
  358.         killer_format = KILLED_BY;
  359.     Strcpy(kilbuf, (!killer || how >= PANICKED ? deaths[how] : killer));
  360.     killer = kilbuf;
  361. #ifdef WIZARD
  362.     if (wizard && how == TRICKED) {
  363.         You("are a very tricky wizard, it seems.");
  364.         return;
  365.     }
  366. #endif
  367.     if (Lifesaved && how <= GENOCIDED) {
  368.         pline("But wait...");
  369.         makeknown(AMULET_OF_LIFE_SAVING);
  370.         Your("medallion %s!",
  371.               !Blind ? "begins to glow" : "feels warm");
  372.         if (how == CHOKING) You("vomit ...");
  373.         You("feel much better!");
  374.         pline("The medallion crumbles to dust!");
  375.         useup(uamul);
  376.  
  377.         (void) adjattrib(A_CON, -1, TRUE);
  378.         if(u.uhpmax <= 0) u.uhpmax = 10;    /* arbitrary */
  379.         savelife(how);
  380.         if (how == GENOCIDED)
  381.             pline("Unfortunately you are still genocided...");
  382.         else {
  383.             killer = 0;
  384.             return;
  385.         }
  386.     }
  387. #if defined(WIZARD) || defined(EXPLORE_MODE)
  388.     if ((wizard || discover) && how <= GENOCIDED) {
  389.         if(yn("Die?") == 'y') goto die;
  390.         pline("OK, so you don't %s.",
  391.             (how == CHOKING) ? "choke" : "die");
  392.         if(u.uhpmax <= 0) u.uhpmax = u.ulevel * 8;    /* arbitrary */
  393.         savelife(how);
  394.         killer = 0;
  395.         return;
  396.     }
  397. #endif /* WIZARD || EXPLORE_MODE */
  398.     /* Sometimes you die on the first move.  Life's not fair.
  399.      * On those rare occasions you get hosed immediately, go out
  400.      * smiling... :-)  -3.
  401.      */
  402.     if (moves <= 1 && how < QUIT)
  403.         /* You die... --More-- */
  404.         pline("Do not pass go.  Do not collect 200 zorkmids.");
  405.  
  406. die:
  407.     if (have_windows) wait_synch();    /* flush screen output */
  408. #ifndef NO_SIGNAL
  409.     (void) signal(SIGINT, (SIG_RET_TYPE) done_intr);
  410. # if defined(UNIX) || defined(VMS)
  411.     (void) signal(SIGQUIT, (SIG_RET_TYPE) done_intr);
  412.     (void) signal(SIGHUP, (SIG_RET_TYPE) done_hangup);
  413. # endif
  414. #endif /* NO_SIGNAL /* */
  415. #ifdef POLYSELF
  416.     if (u.mtimedone)
  417.         upmon = uasmon;
  418.     else
  419. #endif
  420.     upmon = player_mon();
  421.  
  422.     if (u.ugrave_arise < 0) { /* >= 0 means create no corpse */
  423.         if (how == STONING)
  424.         u.ugrave_arise = -2;
  425.  
  426. /*
  427.  * If you're burned to a crisp, why leave a corpse?
  428.  */
  429.         else if (how != BURNING && how != PANICKED)
  430.         (void) mk_named_object(CORPSE, upmon, u.ux, u.uy, plname,
  431.                             (int)strlen(plname));
  432.     }
  433.  
  434.     if (how == QUIT) {
  435.         killer_format = NO_KILLER_PREFIX;
  436.         if (u.uhp < 1) {
  437.             how = DIED;
  438. /* note that killer is pointing at kilbuf */
  439.             Strcpy(kilbuf, "quit while already on Charon's boat");
  440.         }
  441.     }
  442.     if (how == ESCAPED || how == PANICKED)
  443.         killer_format = NO_KILLER_PREFIX;
  444.  
  445.     /* paybill() must be called unconditionally, or strange things will
  446.      * happen to bones levels */
  447.     taken = paybill(how != QUIT);
  448.     paygd();
  449.     clearlocks();
  450. #ifdef AMIGA
  451.     clear_icon();
  452. #endif
  453.     if (have_windows) display_nhwindow(WIN_MESSAGE, FALSE);
  454.  
  455.     if (flags.end_disclose && how != PANICKED) disclose(how,taken);
  456.  
  457.     if (how < GENOCIDED) {
  458. #ifdef WIZARD
  459.         if (!wizard || yn("Save bones?") == 'y')
  460. #endif
  461.         savebones();
  462.     }
  463.  
  464.     /* clean up unneeded windows */
  465.     if (have_windows) {
  466.         destroy_nhwindow(WIN_MAP);
  467.         destroy_nhwindow(WIN_STATUS);
  468.         destroy_nhwindow(WIN_MESSAGE);
  469.  
  470.         if(!done_stopprint || flags.tombstone)
  471.         endwin = create_nhwindow(NHW_TEXT);
  472.  
  473.         if(how < GENOCIDED && flags.tombstone) outrip(how, endwin);
  474.     } else
  475.         done_stopprint = 1; /* just avoid any more output */
  476.  
  477. /* changing kilbuf really changes killer. we do it this way because
  478.    killer is declared a (const char *)
  479. */
  480.     if (u.uhave.amulet) Strcat(kilbuf, " (with the Amulet)");
  481.     if (!done_stopprint) {
  482.         Sprintf(pbuf, "%s %s the %s...",
  483.            (pl_character[0]=='S') ? "Sayonara" : "Goodbye", plname,
  484.            how != ASCENDED ? (const char *) pl_character :
  485.            (const char *) (flags.female ? "Demigoddess" : "Demigod"));
  486.         putstr(endwin, 0, pbuf);
  487.         putstr(endwin, 0, "");
  488.     }
  489.     {   long tmp;
  490.         int deepest = deepest_lev_reached(FALSE);
  491.  
  492.         u.ugold += hidden_gold();    /* accumulate gold from containers */
  493.         tmp = u.ugold - u.ugold0;
  494.         if (tmp < 0L)
  495.         tmp = 0L;
  496.         if (how < PANICKED)
  497.         tmp -= tmp / 10L;
  498.         u.urexp += tmp;
  499.         u.urexp += 50L * (long)(deepest - 1);
  500.         if (deepest > 20)
  501.         u.urexp += 1000L * (long)((deepest > 30) ? 10 : deepest - 20);
  502.         if (how == ASCENDED) u.urexp *= 2L;
  503.     }
  504.     if (how == ESCAPED || how == ASCENDED) {
  505.         register struct monst *mtmp;
  506.         register struct obj *otmp;
  507.         struct obj *jewels;
  508.         long i;
  509.         register long worthlessct = 0;
  510.  
  511.         /*
  512.          *  Put items that count into the jewels chain.  Rewriting
  513.          *  the invent chain and all the container chains (within
  514.          *  invent) here is safe.  They will never be used again.
  515.          */
  516.         jewels = get_valuables(invent);
  517.  
  518.         /* add points for jewels */
  519.         for(otmp = jewels; otmp; otmp = otmp->nobj) {
  520.             if(otmp->oclass == GEM_CLASS)
  521.                 u.urexp += otmp->quan *
  522.                         objects[otmp->otyp].oc_cost;
  523.             else    /* amulet */
  524.                 u.urexp += objects[otmp->otyp].oc_cost;
  525.         }
  526.  
  527.         keepdogs();
  528.         viz_array[0][0] |= IN_SIGHT; /* need visibility for naming */
  529.         mtmp = mydogs;
  530.         if(!done_stopprint) Strcpy(pbuf, "You");
  531.         if(mtmp) {
  532.             while(mtmp) {
  533.                 if(!done_stopprint) {
  534.                     Strcat(pbuf, " and ");
  535.                     Strcat(pbuf, mon_nam(mtmp));
  536.                 }
  537.                 if(mtmp->mtame)
  538.                     u.urexp += mtmp->mhp;
  539.                 mtmp = mtmp->nmon;
  540.             }
  541.             if(!done_stopprint)
  542.                 putstr(endwin, 0, pbuf);
  543.             pbuf[0] = 0;
  544.         } else {
  545.             if(!done_stopprint)
  546.                 Strcat(pbuf, " ");
  547.         }
  548.         if(!done_stopprint) {
  549.             Sprintf(eos(pbuf),
  550.                 "%s with %ld point%s,",
  551.                 how==ASCENDED ? "went to your reward"
  552.                 : "escaped from the dungeon",
  553.                 u.urexp, plur(u.urexp));
  554.             putstr(endwin, 0, pbuf);
  555.         }
  556.  
  557.         /* print jewels chain here */
  558.         for(otmp = jewels; otmp; otmp = otmp->nobj) {
  559.             makeknown(otmp->otyp);
  560.             if(otmp->oclass == GEM_CLASS &&
  561.                otmp->otyp < LUCKSTONE) {
  562.                 i = otmp->quan *
  563.                     objects[otmp->otyp].oc_cost;
  564.                 if(i == 0) {
  565.                     worthlessct += otmp->quan;
  566.                     continue;
  567.                 }
  568.             } else {        /* amulet */
  569.                 otmp->known = 1;
  570.                 i = objects[otmp->otyp].oc_cost;
  571.             }
  572.             if(!done_stopprint) {
  573.                 Sprintf(pbuf, "        %s (worth %ld zorkmids),",
  574.                     doname(otmp), i);
  575.                 putstr(endwin, 0, pbuf);
  576.             }
  577.         }
  578.         if(worthlessct && !done_stopprint) {
  579.             Sprintf(pbuf,
  580.               "        %ld worthless piece%s of colored glass,",
  581.               worthlessct, plur(worthlessct));
  582.             putstr(endwin, 0, pbuf);
  583.         }
  584.     } else if (!done_stopprint) {
  585.         Strcpy(pbuf, "You ");
  586.         Strcat(pbuf, ends[how]);
  587.         if (how != ASCENDED) {
  588.             Strcat(pbuf, " in ");
  589.             if (Is_astralevel(&u.uz))
  590.             Strcat(pbuf, "The Astral Plane");
  591.             else Strcat(pbuf, dungeons[u.uz.dnum].dname);
  592.             Strcat(pbuf, " ");
  593.             if (!In_endgame(&u.uz)
  594. #ifdef MULDGN
  595.                            && !Is_knox(&u.uz)
  596. #endif
  597.             )
  598.             Sprintf(eos(pbuf), "on dungeon level %d ", (
  599. #ifdef MULDGN
  600.                          In_quest(&u.uz) ?
  601.                             dunlev(&u.uz) :
  602. #endif
  603.                             depth(&u.uz)));
  604.         }
  605.         Sprintf(eos(pbuf),
  606.             "with %ld point%s,", u.urexp, plur(u.urexp));
  607.         putstr(endwin, 0, pbuf);
  608.     }
  609.     if (!done_stopprint) {
  610.         Sprintf(pbuf, "and %ld piece%s of gold, after %ld move%s.",
  611.             u.ugold, plur(u.ugold), moves, plur(moves));
  612.         putstr(endwin, 0, pbuf);
  613.     }
  614.     if (!done_stopprint) {
  615.         Sprintf(pbuf,
  616.          "You were level %u with a maximum of %d hit point%s when you %s.",
  617.             u.ulevel, u.uhpmax, plur(u.uhpmax), ends[how]);
  618.         putstr(endwin, 0, pbuf);
  619.         putstr(endwin, 0, "");
  620.     }
  621. #if (defined(WIZARD) || defined(EXPLORE_MODE))
  622. # ifndef LOGFILE
  623.     if (wizard || discover) {
  624.         if (!done_stopprint) {
  625.         putstr(endwin, 0, "");
  626.         Sprintf(pbuf, "Since you were in %s mode, the score list \
  627. will not be checked.", wizard ? "wizard" : "discover");
  628.         putstr(endwin, 0, pbuf);
  629.         putstr(endwin, 0, "");
  630.         display_nhwindow(endwin, TRUE);
  631.         }
  632.         if (have_windows)
  633.         exit_nhwindows(NULL);
  634.     } else
  635. # endif
  636. #endif
  637.     {
  638.         if (!done_stopprint)
  639.         display_nhwindow(endwin, TRUE);
  640.         if (have_windows)
  641.         exit_nhwindows(NULL);
  642. /* "So when I die, the first thing I will see in Heaven is a score list?" */
  643.         topten(how);
  644.     }
  645.     if(done_stopprint) { raw_print(""); raw_print(""); }
  646.     terminate(0);
  647. }
  648.  
  649.  
  650. #ifdef NOSAVEONHANGUP
  651. int
  652. hangup()
  653. {
  654.     (void) signal(SIGINT, SIG_IGN);
  655.     clearlocks();
  656. # ifndef VMS
  657.     terminate(1);
  658. # endif
  659. }
  660. #endif
  661.  
  662.  
  663. void
  664. container_contents(list, identified, all_containers)
  665.     struct obj *list;
  666.     boolean identified, all_containers;
  667. {
  668.     register struct obj *box, *obj;
  669.     char buf[BUFSZ];
  670.  
  671.     for (box = list; box; box = box->nobj) {
  672.         if (Is_container(box) && box->otyp != BAG_OF_TRICKS) {
  673.         if (box->cobj) {
  674.             winid tmpwin = create_nhwindow(NHW_MENU);
  675.             Sprintf(buf, "Contents of the %s:", xname(box));
  676.             putstr(tmpwin, 0, buf); putstr(tmpwin, 0, "");
  677.             for (obj = box->cobj; obj; obj = obj->nobj) {
  678.             if (identified) {
  679.                 makeknown(obj->otyp);
  680.                 obj->known = obj->bknown = obj->dknown = 1;
  681.             }
  682.             putstr(tmpwin, 0, doname(obj));
  683.             }
  684.             display_nhwindow(tmpwin, TRUE);
  685.             destroy_nhwindow(tmpwin);
  686.             if (all_containers)
  687.             container_contents(box->cobj, identified, TRUE);
  688.         } else {
  689.             pline("%s is empty.", The(xname(box)));
  690.             display_nhwindow(WIN_MESSAGE, FALSE);
  691.         }
  692.         }
  693.         if (!all_containers)
  694.         break;
  695.     }
  696. }
  697.  
  698. void
  699. terminate(status)
  700. int status;
  701. {
  702. #ifdef MAC
  703.     if (!hu) {
  704.         int idx;
  705.         for (idx = theWindows[BASE_WINDOW].windowTextLen; --idx >= 0; )
  706.             /* If there is something to show... */
  707.             if (((unsigned char *)*theWindows[BASE_WINDOW].windowText)[idx] > ' ') {
  708.                 display_nhwindow(BASE_WINDOW, TRUE);
  709.                 break;
  710.             }
  711.     }
  712. #endif
  713.     exit(status);
  714. }
  715.  
  716. /*end.c*/
  717.